#define DEBUG
#include <cstdio>
#include <cstring>

using namespace std;

const int maxn=5, maxm=200000, inf=0x7ffffff;

int n, m, map[maxn+1][maxm+1];

int min(int a, int b) {
  return a<b ? a : b;
}

int max(int a, int b) {
  return a>b ? a : b;
}

class SegmentTree {
public:
  int dis[4*maxm+1][maxn+1][maxn+1];

  void merge(int dis[maxn+1][maxn+1], int dis1[maxn+1][maxn+1], int dis2[maxn+1][maxn+1]) {
    for (int i=1; i<=n; i++) {
      for (int j=1; j<=n; j++) {
	dis[i][j] = inf;
	for (int k=1; k<=n; k++) {
	  dis[i][j] = min(dis[i][j], dis1[i][k]+dis2[k][j]+1);
	}
      }
    }
  }

  void updatePoint(int o, int p) {
    for (int i=1; i<=n; i++) {
      bool flag=true;
      for (int j=i; j>0; j--) {
	if (flag && map[j][p]) {
	  dis[o][i][j] = i-j;
	} else {
	  dis[o][i][j] = inf;
	  flag = false;
	}
      }
      flag = true;
      for (int j=i; j<=n; j++) {
	if (flag && map[j][p]) {
	  dis[o][i][j] = j-i;
	} else {
	  dis[o][i][j] = inf;
	  flag = false;
	}
      }
    }
  }

  void init(int o, int l, int r) {
    if (l==r) {
      updatePoint(o, l);
    } else {
      int mid=(l+r)/2;
      init(o*2, l, mid);
      init(o*2+1, mid+1, r);
      merge(dis[o], dis[o*2], dis[o*2+1]);
    }
  }

  void update(int o, int l, int r, int t) {
    if (l==r) {
      updatePoint(o, l);
    } else {
      int mid=(l+r)/2;
      if (t<=mid) {
	update(o*2, l, mid, t);
      } else {
	update(o*2+1, mid+1, r, t);
      }
      merge(dis[o], dis[o*2], dis[o*2+1]);
    }
  }

  void get(int o, int l, int r, int tl, int tr, int ans[maxn+1][maxn+1], bool &flag) {
    static int temp[maxn+1][maxn+1];
    if (l==tl && r==tr) {
      if (flag) {
	memcpy(temp, ans, sizeof temp);
	merge(ans, temp, dis[o]);
      } else {
	memcpy(ans, dis[o], sizeof dis[o]);
	flag = true;
      }
    } else {
      int mid=(l+r)/2;
      if (tl<=mid && tr>=l) {
	get(o*2, l, mid, max(tl, l), min(tr, mid), ans, flag);
      }
      if (tl<=r && tr>mid) {
	get(o*2+1, mid+1, r, max(tl, mid+1), min(tr, r), ans, flag);
      }
    }
  }
};

int main() {
  freopen("maze.in", "r", stdin);
  freopen("maze.out", "w", stdout);
  
  static SegmentTree sgt;
  int q;
  scanf("%d %d %d", &n, &m, &q);
  for (int i=1; i<=n; i++) {
    for (int j=1; j<=m; j++) {
      scanf("%d", &map[i][j]);
    }
  }
  sgt.init(1, 1, m);

  for (int i=1; i<=q; i++) {
    int opt;
    scanf("%d", &opt);
    if (opt==1) {
      int a, b;
      scanf("%d %d", &a, &b);
      map[a][b] = !map[a][b];
      sgt.update(1, 1, m, b);
    } else {
      static int ans[maxn+1][maxn+1];
      memset(ans, 0, sizeof ans);
      int a, b, c, d;
      scanf("%d %d %d %d", &a, &b, &c, &d);
      bool flag=false;
      sgt.get(1, 1, m, b, d, ans, flag);
      if (ans[a][c]>=inf) {
	printf("-1\n");
      } else {
	printf("%d\n", ans[a][c]);
      }
    }
  }

  fclose(stdin);
  fclose(stdout);
  return 0;
}
